package org.sunriz.server;

import org.sunriz.DAO.Signal;
import org.sunriz.utils.Constant;
import org.sunriz.utils.FolderUtil;
import org.sunriz.utils.GetName;
import org.sunriz.utils.FileCheck;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.*;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Matcher;

import static org.sunriz.utils.RegexManager.*;

public class RefactorInput {

    public static void refactor(HashMap<String, List<Signal>> outputInfo){
        // 获取文件列表
        List<File> fileList = FolderUtil.getFileList();

        for (File file : fileList) {

            String fileName = file.getName();
            // 获取文件名
            System.out.println("Input处理文件: " + fileName);

            // 标记文件是否被修改
            AtomicBoolean modified = new AtomicBoolean(false);

            List<String> lines;
            try {
                lines = Files.readAllLines(file.toPath(), Charset.forName(Constant.ENCODING));
                for (int i = 0; i < lines.size() - 1; i++) {
                    String line = lines.get(i);

                    // 如果是Func，那么判断是否是PgAI//PgDI
                    Matcher funcPattern = FUNC_PATTERN.matcher(line);
                    if (funcPattern.find()) {
                        // 寻找输入点
                        if (line.contains(Constant.PgAI)||line.contains(Constant.PgDI)) {
                            Matcher matcher = TYPE_PATTERN.matcher(line);
                            matcher.find();

                            // 获取name以及是type（PgAI/PgDI）
                            String type = matcher.group(0).trim();
                            String nameLine = lines.get(i + 3);
                            String name = GetName.getLastName(nameLine);
                            String paraLine = lines.get(i + 2);

                            int finalI = i;
                            outputInfo.forEach((CuName, signals1) -> {
                                // 判断是否是同一个控制器输出点
                                if (file.getName().equals(CuName)){
                                    List<Signal> signals11 = signals1;

                                    for (int j = 0; j < signals11.size(); j++) {
                                        Signal signal = signals11.get(j);

                                        if (signal.getName() != null && signal.getName().equals(name)) {
                                            String type1 = signal.getType();
                                            // 多重校验:如果输入点是DI，那么对应的输出点必须是DO，AI同理
                                            if (type.substring(0, 3).equals(type1.substring(0,3)) && !type.substring(3, 4).equals(type1.substring(3, 4))) {
                                                String pageNumber = signal.getPageNumber();
                                                String blockID = signal.getBlockID();
                                                String s = alterParaLine(paraLine, pageNumber, blockID);
                                                lines.set(finalI +2,s);

                                                modified.set(true);
                                            }

                                        }
                                    }
                                }else {
                                    // TODO 如果是其他控制器，额外方法（添加下网点/表格）
                                    otherCu();
                                }
                            });


                        }
                    }
                }
                
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            storeFile(file,lines,modified);
        }
    }


    /**
     * 将修改后的文件存储到文件夹
     * @param file 文件
     * @param lines 行
     * @param modified 是否修改
     */
    private static void storeFile(File file, List<String> lines, AtomicBoolean modified) {
        try {
            // 获取备份目录路径
            Path backupDir = FolderUtil.getFilePath();
            // 创建目标文件路径
            Path targetPath = backupDir.resolve(file.getName());

            if (modified.get()) {
                // 处理修改过的文件 - 将新内容写入新文件
                Files.write(
                        targetPath,
                        lines,
                        Charset.forName(Constant.ENCODING),  // 使用GBK编码
                        StandardOpenOption.CREATE,
                        StandardOpenOption.TRUNCATE_EXISTING  // 清除旧内容
                );

                // 检查文件行数是否一致
                boolean check = FileCheck.checkLineCount(file.getAbsolutePath(), targetPath.toString());
                if (!check) {
                    System.out.println("文件行数不一致，请检查文件: " + file.getName());
                }


                System.out.println("✅ 修改内容已写入: " + targetPath);
            } else {
                // 处理未修改的文件 - 直接复制原始文件
                Files.copy(
                        file.toPath(),
                        targetPath,
                        StandardCopyOption.REPLACE_EXISTING
                );
                System.out.println("ⓘ 原始文件已复制: " + targetPath);
            }
        } catch (IOException e) {
            throw new RuntimeException("文件备份失败: " + e.getMessage(), e);
        }
    }

    /**
     * 将引用行进行修改
     */
    private static String alterParaLine(String ParaLine,String page,String block){
        // 定位关键字符的位置
        int indexB = ParaLine.indexOf('B');
        if (indexB == -1) {
            throw new IllegalArgumentException("字符 'B' 未找到");
        }

        int firstCommaIndex = ParaLine.indexOf(',', indexB + 1);
        if (firstCommaIndex == -1) {
            throw new IllegalArgumentException("第一个逗号未找到");
        }

        int secondCommaIndex = ParaLine.indexOf(',', firstCommaIndex + 1);
        if (secondCommaIndex == -1) {
            throw new IllegalArgumentException("第二个逗号未找到");
        }

        // 分割字符串
        String prefix = ParaLine.substring(0, indexB + 1); // 包含 "B"
        String value1 = ParaLine.substring(indexB + 1, firstCommaIndex);
        String value2 = ParaLine.substring(firstCommaIndex + 1, secondCommaIndex);
        String suffix = ParaLine.substring(secondCommaIndex); // 包含剩余部分

        // 替换值并拼接结果
        String result = prefix + page + "," + block + suffix;
        return result;
    }

    /**
     * 如果是其他控制器，额外方法（添加下网点/表格）
     */
    private static void otherCu(){

    }
}
